package cn.xchats.onlinetraffic.jooq.frame;


import cn.xchats.onlinetraffic.jooq.frame.dsl.*;
import org.hibernate.validator.constraints.NotEmpty;
import org.jooq.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Repository;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
import org.jooq.impl.DSL;


/**
 * jooq
 * <p>@author txd.cool@gmail.com</p>
 * <p>2017年5月12日</p>
 * <p>version 1.0</p>
 */
@Repository
public class JooqRepository  {


	public JooqRepository(){
	}

	@Autowired
	@Qualifier("dslContextDefault")
	protected DSLContext dsl;

	//查
	public  <T,R extends Record> List<T> dslSelect(@NotNull(
			message="查询SQL不能为空"
	) DslSelect<R> dslSelect, Class<T> clazz) {
		return dslSelect.select(this.dsl).fetchInto(clazz);
	}

	public <T,R extends Record> List<T> listByCondition(@NotNull(
			message="表对象不能为空"
	)Table<R> table, Class<T> clazz ){
		return this.dsl.select().from(table).fetchInto(clazz);
	}

	public <T,R extends Record> List<T> listByCondition(@NotNull(
			message="表对象不能为空"
	)Table<R> table, Class<T> clazz, Condition condition ){
		return this.dsl.select().from(table).where(condition).fetchInto(clazz);
	}

	//listByCriteria
	//return record
	public <R extends Record> List<R> listByCondition(@NotNull(
			message="表对象不能为空"
	)Table<R> table, Condition condition){
		return this.dsl.select().from(table).where(condition).fetchInto(table);
	}

	public <R extends Record> List<R> listByCondition(@NotNull(
			message="表对象不能为空"
	)Table<R> table){
		return this.dsl.select().from(table).fetchInto(table);
	}

	//count
	public  <T,R extends Record> int dslSelectCount(@NotNull(
			message="查询SQL不能为空"
	) DslSelect<R> dslSelect) {
		return  dsl.fetchCount(dslSelect.select(this.dsl));
	}

	//改
	public <R extends Record> Integer dslUpdate(@NotNull(
			message="更新SQL不能为空"
	) DslUpdate<R> dslUpdate){
		return dslUpdate.update(this.dsl).execute();
	}

	public <R extends UpdatableRecord<R>> int[] batchModify(@NotEmpty(message="数据实体集不能为空") List<R> rs){
		return this.dsl.batchUpdate(rs).execute();
	}

	public <T,R1 extends Record,R2 extends UpdatableRecord<R2>> int[] batchModify(@NotNull(
			message="表对象不能为空"
	)Table<R1> table,
																				  @NotEmpty(
																						  message="数据实体集不能为空"
																				  )List<T> rs){
		List<R2> records=new ArrayList<>();
		rs.forEach(r -> records.add((R2) this.dsl.newRecord(table,r)));
		return this.batchModify(records);
	}

	//删
	public <R extends Record> Integer dslDelete(@NotNull(
			message="删除SQL不能为空")
														DslDelete<R> dslDelete){
		return dslDelete.delete(this.dsl).execute();
	}

	public <R extends UpdatableRecord<R>> int[] batchDelete(@NotEmpty(message="数据实体集不能为空") List<R> rs){
		return this.dsl.batchDelete(rs).execute();
	}

	public <T,R1 extends Record,R2 extends UpdatableRecord<R2>> int[] batchDelete(@NotNull(
			message="表对象不能为空"
	)Table<R1> table,
																				  @NotEmpty(
																						  message="数据实体集不能为空"
																				  )List<T> rs){
		List<R2> records=new ArrayList<>();
		rs.forEach(r -> { R2 newRecord = (R2) this.dsl.newRecord(table, r);records.add(newRecord);});
		return this.batchDelete(records);
	}

	//添
	public <R extends Record> Integer dslInsert(@NotNull(
			message="插入SQL不能为空"
	)DslInsert<R> dslInsert){
		return dslInsert.dslInsert(this.dsl).execute();
	}

	public <R extends UpdatableRecord<R>> int[] batchCreate(List<R> rs){
		return this.dsl.batchInsert(rs).execute();
	}

	public <T,R1 extends Record,R2 extends UpdatableRecord<R2>> int[] batchCreate(@NotNull(
			message="表对象不能为空"
	)Table<R1> table,
																				  @NotEmpty(
																						  message="数据实体集不能为空"
																				  )List<T> rs){
		List<R2> records=new ArrayList<>();
		rs.forEach(r->records.add((R2) this.dsl.newRecord(table,r)));
		return this.batchCreate(records);
	}

	public <T,R extends TableRecord<R>> T create(@NotNull(
			message = "模型Class不能为空"
	)Class<T> clazz,
												 @NotNull(
														 message = "数据实体不能为空"
												 )R r){
		T t = r.into(clazz);
		try{
			if (r.insert()==1) {
				return t;
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return t;
	}

	public <T,R extends Record> T create(@NotNull(
			message="表对象不能为空"
	)Table<R> table,
										 @NotNull(
												 message = "模型Class不能为空"
										 )Class<T> clazz,
										 @NotNull(
												 message = "数据实体不能为空"
										 )T t){
		TableRecord newRecord = (TableRecord) this.dsl.newRecord(table,t);
		try{
			return (T) this.create(clazz, newRecord);
		}catch(Exception e){
			return t;
		}
	}

	public <R extends Record> R newRecord(@NotNull(
			message="表对象不能为空"
	)Table<R> table,
										  @NotNull(
												  message="表对象不能为空"
										  )Object obj){
		return this.dsl.newRecord(table,obj);
	}

	public <T,R extends Record> T createException(@NotNull(
			message="表对象不能为空"
	)Table<R> table,
										 @NotNull(
												 message = "模型Class不能为空"
										 )Class<T> clazz,
										 @NotNull(
												 message = "数据实体不能为空"
										 )T t) throws Exception{
		TableRecord newRecord = (TableRecord) this.dsl.newRecord(table,t);
		return (T) this.createException(clazz, newRecord);
	}

	public <T,R extends TableRecord<R>> T createException(@NotNull(
			message = "模型Class不能为空"
	)Class<T> clazz,
												 @NotNull(
														 message = "数据实体不能为空"
												 )R r)throws Exception{
		T t = r.into(clazz);
		if (r.insert()==1) {
			return t;
		}
		return t;
	}

}
